<?php

define('MAX_SCENEID', 100000);
define('QR_EXPIRE_SECONDS', 2592000);
define('QR_SCENE', 'QR_SCENE');
define('QR_LIMIT_SCENE', 'QR_LIMIT_SCENE');
define('QR_LIMIT_STR_SCENE',"QR_LIMIT_STR_SCENE");
define('QR_URL',"QR_URL");
define('QR_IMG_URL', 'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=');

class QRCode {
	public static function add($name,$sceneId,$module, $moduleId = 0, $method = '', 
			$actionName = 'QR_LIMIT_SCENE', $actionInfo ='', $accessTag ='',$cId=null, $userInfo = null) {

		$cId?$customerId=$cId:$customerId = Session::$user["customerId"];
		Session::switchCustomer(0);

        if ($actionName == QR_LIMIT_SCENE) {
			$sceneId = self::getAvailableLimitSceneId($customerId);
		} else if($actionName==QR_SCENE) {
			$sceneId = self::getAvailableNotLimitSceneId($customerId);
		} else if($actionName==QR_URL){
            $sceneId = self::getAvailableQrUrlLimitSceneId($customerId);
        }
		
		if ($sceneId == NULL) {
			Session::switchCustomer($customerId);
			Output::instance()->resultCode(code_qr_scene_no_available);
			return;
		}

		Session::switchCustomer($customerId);
        if($actionName==QR_URL){
            $userShareUrl = '';
            $url = R('MiContent/getH5ServerHost');
            $mishareModel = M('mishare');
            $sid = $mishareModel->where(['module' => $module, 'moduleId' => $userInfo['moduleId']])->getField('id');
            $userShareUrl = $url . "call.html?customerId=" . $customerId . '&module='.$module.'&method='.$method."&params=%7B%22id%22%3A%22".$userInfo['moduleId']."%22%2C%22uid%22%3A%22". $userInfo['uid'] ."%22%2C%22scanId%22%3A%22". $sceneId ."%22%2C%22isDefault%22%3A%222%22%2C%22sid%22%3A%22".$sid."%22%7D";
            $qrCode = R('PhpQRcode/create_qcode',[$userShareUrl,1]);
            $data["ticket"] = $userShareUrl;
            if(empty($qrCode[0]['qr_img'])){
                Log::write('qcodeContentId:'.$userInfo['moduleId']);
            }
        }else{
            $qrcode = self::createQRCode($actionName, $sceneId,null,$customerId);
            if ($qrcode == NULL) {
                return;
            }
            $data["ticket"] = $qrcode->ticket;
        }


		Session::switchCustomer(0);
		
		$QRModel = M("qrcode");
		$data["fromCustomerId"] = $customerId;
		$data["sceneId"] = $sceneId;
		$data["name"] = $name;
		$data["actionName"] = $actionName;
		$data["actionInfo"] = $actionInfo;
		$data["module"] = $module;
		$data["moduleId"] = $moduleId;
		$data["method"] = $method;
		$data["accessTag"] =  $accessTag;
		$data["updateTime"] = date("Y-m-d H:i:s");
		$data["deleted"] = 0;
		if($actionName == QR_URL){
            $data["codeIndex"] = $sceneId;
            $data["ticket"] = $qrCode[0]['qr_img'];
            $result = $QRModel->add($data);
            Log::write("qr_url生成二维码  ".$QRModel->getLastSql());
            $data["img"] = $qrCode[0]['qr_img'];
        }else{
            if ($actionName == QR_LIMIT_SCENE||$actionName==QR_SCENE) {
                $data["codeIndex"] = $sceneId;
            }
            $result=$QRModel->where("ticket='$qrcode->ticket'")->find();
            if((!$result || count($result) < 1 )) {
                $result = $QRModel->add($data);
                Log::write("生成二维码  ".$QRModel->getLastSql());
            }
            $data["img"] = QR_IMG_URL . $qrcode->ticket;
        }
		Session::switchCustomer($customerId);
		if (!$result) {
			Log::write('qrcode add error:' . $QRModel->getLastSql());
			Output::instance()->resultCode(code_sql_error);
			return;
		}
		
		$data["id"] = $result;
		return $data;
	}
	
	
	public static function getByModule($module, $moduleId) {
		$customerId = Session::$user["customerId"];
		Session::switchCustomer(0);
		
		$QRModel = M("qrcode");
		
		$where["module"] = $module;
		$where["moduleId"] = $moduleId;
		$where["fromCustomerId"] = $customerId;
		$where["deleted"] = 0;
		$qrcode = $QRModel->where($where)->find();
		// 		echo $QRModel->getLastSql();
		if ($qrcode) {
			$qrcode["img"] = QR_IMG_URL . $qrcode["ticket"];
		}
		Session::switchCustomer($customerId);
		return $qrcode;
	}

    /*
     * 获取临时可用的二维码id
    */
    private static function getAvailableQrUrlLimitSceneId($customerId) {
        $QRModel = M("qrcode");
        $where["deleted"] = 0;
        $where["fromCustomerId"] = $customerId;
        $where["actionName"] = QR_URL;
        $sceneId = $QRModel->where($where)->min("codeIndex");
        if ($sceneId == NULL) {
            $sceneId =  - 1;
        } else {
            $sceneId = $sceneId - 1;
        }
        return $sceneId;
    }
	
	
	/*
	 * 获取临时可用的二维码id
	*/
	private static function getAvailableNotLimitSceneId($customerId) {
		$QRModel = M("qrcode");
		$where["deleted"] = 0;
		$where["fromCustomerId"] = $customerId;
		$where["actionName"] = QR_SCENE;
		$sceneId = $QRModel->where($where)->max("codeIndex");
		if ($sceneId == NULL) {
			$sceneId = MAX_SCENEID + 1;
		} else {
			$sceneId = $sceneId + 1;
		}
		return $sceneId;
	}
	
	/*
	 * 获取永久可用的二维码id
	*/
	private static function getAvailableLimitSceneId($customerId) {
		$QRModel = M("qrcode");
		
		$where["deleted"] = 1;
		$where["fromCustomerId"] = $customerId;
		$where["actionName"] = QR_LIMIT_SCENE;
		$where["sceneId"] = array('exp', 'IS NOT NULL');
	
		$sceneId = $QRModel->where($where)->getField('sceneId');
	
		if ($sceneId == NULL) {
			// 被删除的数据sceneId不为空，被删除的数据且sceneId被复用的把sceneId设为NULL
			$condition['deleted'] = array('eq',0);
			$condition['actionName'] = array('eq',QR_LIMIT_SCENE);
			$condition['fromCustomerId'] = array('eq',$customerId);
				
			$sceneId = $QRModel->where($condition)->max("codeIndex");
				
			if ($sceneId == NULL) {
				$sceneId = 1;
			} else if ($sceneId < MAX_SCENEID) {
				$sceneId = (int)$sceneId + 1;
			}
		}
		
		return $sceneId;
	}
	
	
	public function createQRCode($action_name, $sceneId,$expireSeconds = NULL,$cid=null) {
		$result = self::createTicket($action_name, $sceneId,$expireSeconds,$cid);
		if ($result == NULL) {
			return NULL;
		} else if($result->errcode != 0) {
			if ($result->errcode == 48001) {
				Output::instance()->resultCode(code_userinfo_api_auth);
				return NULL;
			}
			Log::write('create qr error code:' . $result->errcode);
			Log::write($result->errmsg);
			Output::instance()->resultCode(code_qr_create_error, '二维码生成失败，' . $result->errmsg);
			return NULL;
		} else {
			return $result;
		}
	}
	
	private function createTicket($action_name, $sceneId,$expireSeconds,$cid=null) {
		$param["action_name"] = $action_name;
		if($action_name == QR_SCENE || $action_name == QR_LIMIT_SCENE){
			$id["scene_id"] = (int)$sceneId;
		}
		if($action_name==QR_LIMIT_STR_SCENE) {
			$id["scene_str"] = $sceneId;
		}
		$scene["scene"] = $id;
		if ($action_name == QR_SCENE) {
			if ($expireSeconds == NULL) {
				$param["expire_seconds"] = QR_EXPIRE_SECONDS;
			} else {
				$param["expire_seconds"] = $expireSeconds;
			}
		}
		$param["action_info"] = $scene;
		$param = json_encode($param);
		// 		Log::write($param);
	
		$access_token = WeixinApi::getAccessToken(true,$cid);
		if (!isset($access_token)) {
			return NULL;
		}
	
		$url='https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=' . $access_token;
		Log::write($url);
	
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_POST, 1);
		curl_setopt($ch, CURLOPT_HEADER, 0);
		curl_setopt($ch, CURLOPT_URL,$url);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
		curl_setopt($ch, CURLOPT_POSTFIELDS, $param);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		$result = curl_exec($ch);
		curl_close($ch);
		// 		Log::write($result);
		$result = json_decode($result);
		return $result;
	}
}